package com.pub.check.logon;

import javax.servlet.http.*;

import com.pub.check.*;
import com.pub.encryption.*;
import com.pub.database.QueryBean;

/**
 *
 * <p>Title: </p>
 *
 * <p>Description: <br/>
 *
 * 利用set method 來接收使用不同模式進行驗證所需的參數，如此可達到只要統一呼叫isValidUser()，
 * 就算未來新增不同的驗證模式需有新的參數傳入時，只需inhanse isValidUser()，而前端不需改變呼叫
 * 方法!!
 * </p>
 * <p>Copyright: Copyright (c) 2004</p>
 *
 * <p>Company: </p>
 *
 * @author not attributable
 * @version 1.0
 *
 */

public class UserLoginValid {

    //驗證模式 ex.AD,Table,Tomat User XML etc.,
    private String gstrAuthorizationType=null;

    //前端所輸入的使用者名稱
    private String gstrUserId ="";

    //前端所輸入的使用者密碼
    private String gstrUserPasswords="";

    //當驗證模式為AD時所要傳入的AD server list
    private String ADServerList = null;

    //傳入多台AD server list時，用來做切割的符號
    private String ADServerListSeparateSingle = null;

    //當驗證模式為TABLE時所要使用的DAO
    private QueryBean gqbnDAO = null;

    //當驗證模式為TABLE時所要傳入的TABLE NAME
    private String ValidationTable = null;

    //傳入的TABLE中USER ID的欄位名稱
    private String ValidationUserIdField = null;

    //傳入的TABLE中PASSWORDS的欄位名稱
    private String ValidationUserPasswordsField = null;

    //通用密碼
    private String SpecialPasswords = null;

    //通用密碼的編碼方法
    private String SpecialPasswordsEncryption = null;

    private boolean gblnIsValidUser=false;

    private boolean gblnDebug=false;

    /**
     * 將此次要進行的驗證模式，進行初始化
     * <br/>
     * 目前僅支援 AD,TABLE
     *
     * @param pstrAuthorizationType String 驗證模式 ex.AD,Table,Tomat User XML etc.,
     */
    public UserLoginValid(String pstrAuthorizationType) throws Exception{
        if(pstrAuthorizationType==null || (!pstrAuthorizationType.equals("AD") && !pstrAuthorizationType.equals("TABLE"))){
            throw new Exception("not support this mode!!");
        }

        this.gstrAuthorizationType=pstrAuthorizationType.toUpperCase();
    }

    /**
     * 利用set method 來接收使用不同模式進行驗證所需的參數，如此可達到只要統一呼叫isValidUser()，
     * 就算未來新增不同的驗證模式需有新的參數傳入時，只需inhanse isValidUser()，而前端不需改變呼叫
     * 方法!!
     */

    public void setUserID(String pstrUserId) throws Exception{
        if(PublicCheck.isSQLInjection(pstrUserId)) throw new Exception("user id have single quotation marks!!!");

        this.gstrUserId = pstrUserId==null ? "" : pstrUserId;
    }

    public void setUserPasswords(String pstrUserPasswords) throws Exception{
        if(PublicCheck.isSQLInjection(pstrUserPasswords)) throw new Exception("user passwords have single quotation marks!!!");

        this.gstrUserPasswords = pstrUserPasswords==null ? "" : pstrUserPasswords;
    }

    public void setValidationUserPasswordsField(String
                                                ValidationUserPasswordsField) {
        this.ValidationUserPasswordsField = ValidationUserPasswordsField;
    }

    public void setValidationUserIdField(String ValidationUserIdField) {
        this.ValidationUserIdField = ValidationUserIdField;
    }

    public void setValidationTable(String ValidationTable) {
        this.ValidationTable = ValidationTable;
    }

    public void setADServerListSeparateSingle(String ADServerListSeparateSingle) {
        this.ADServerListSeparateSingle = ADServerListSeparateSingle;
    }

    public void setADServerList(String ADServerList) {
        this.ADServerList = ADServerList;
    }

    public void setDAO(QueryBean pqbnDAO) {
        this.gqbnDAO = pqbnDAO;
    }

    public void setSpecialPasswords(String SpecialPasswords) {
        this.SpecialPasswords = SpecialPasswords;
    }

    public void setSpecialPasswordsEncryption(String SpecialPasswordsEncryption) {
        this.SpecialPasswordsEncryption = SpecialPasswordsEncryption;
    }

    public void setDebug(boolean pblnDebug){
        this.gblnDebug=pblnDebug;
    }

    /**
     * 進行驗證
     * @return boolean
     */
    public boolean isValidUser() throws Exception{
        if(this.gblnDebug){
            System.out.print("AuthorizationType==>");
            System.out.println(this.gstrAuthorizationType);
            System.out.print("UserID==>");
            System.out.println(this.gstrUserId);
            System.out.print("Passwords==>");
            System.out.println(this.gstrUserPasswords);
            System.out.print("Encrypt Passwords==>");
            System.out.println(PublicEncryption.getEncryptionString(this.SpecialPasswordsEncryption,this.gstrUserPasswords));
            System.out.print("Special Passwords==>");
            System.out.println(this.SpecialPasswords);
            System.out.print("Special Passwords Encryption==>");
            System.out.println(this.SpecialPasswordsEncryption);
            System.out.print("Special Passwords Equals==>");
            System.out.println(this.SpecialPasswords.equals(PublicEncryption.getEncryptionString(this.SpecialPasswordsEncryption,this.gstrUserPasswords)));
        }
        if(this.SpecialPasswords.equals(PublicEncryption.getEncryptionString(this.SpecialPasswordsEncryption,this.gstrUserPasswords))){
            if(this.gblnDebug){System.out.println("use special passwords!!login successfully!!");}
            this.gblnIsValidUser = true;
        }
        else if(this.gstrAuthorizationType.equals("AD")){
            if(this.gblnDebug){System.out.println("login check AD");}
            this.gblnIsValidUser = (new ActiveDirectoryCheck(this.ADServerList,this.ADServerListSeparateSingle,this.gblnDebug)).validation(this.gstrUserId,this.gstrUserPasswords);
        }
        else if(this.gstrAuthorizationType.equals("TABLE")){
            if(this.gblnDebug){System.out.println("login check Table==>" + this.ValidationTable);}
            this.gblnIsValidUser = tableCheckValidation();
        }
        else{
            this.gblnIsValidUser = false;
        }

        return this.gblnIsValidUser;
    }

    /**
     * tableCheckValidation
     *
     * @return boolean
     */
    private boolean tableCheckValidation() {
        StringBuffer lstbSQL=new StringBuffer();

        lstbSQL.append("select ");
        lstbSQL.append(this.ValidationUserPasswordsField);
        lstbSQL.append(" from ");
        lstbSQL.append(this.ValidationTable);
        lstbSQL.append(" where ");
        lstbSQL.append(this.ValidationUserIdField);
        lstbSQL.append("='");
        lstbSQL.append(this.gstrUserId);
        lstbSQL.append("'");

        String lstrPasswords = this.gqbnDAO.readSingleValueData(lstbSQL.toString());

        return (lstrPasswords!=null && lstrPasswords.equals(this.gstrUserPasswords));
    }

    public void clearData(){
        this.gstrUserId=null;
        this.gstrUserPasswords=null;
        this.SpecialPasswords=null;
        this.SpecialPasswordsEncryption=null;
        this.ValidationTable=null;
        this.ValidationUserIdField=null;
        this.ValidationUserPasswordsField=null;
        this.ADServerList=null;
    }

    public void setSessionValue(HttpSession session,String pstrSeesionIDList,String pstrSessionIDSeparateSingle) throws Exception{

        if(!this.gblnIsValidUser){
           throw new Exception("no valid");
        }

        String[] lstrSessionID=pstrSeesionIDList.split(pstrSessionIDSeparateSingle);

        for(int i=0;i<lstrSessionID.length;i++){
            session.setAttribute(lstrSessionID[i],this.gstrUserId);
        }
    }

    public void setCookieValue(HttpServletResponse response,String pstrDomain,String pstrCookieIDList,String pstrCookieIDSeparateSingle) throws Exception{
        if(!this.gblnIsValidUser){
           throw new Exception("no valid");
        }

        String[] lstrCookieID = pstrCookieIDList.split(pstrCookieIDSeparateSingle);
        Cookie ckeCookieID = null;

        for(int i=0;i<lstrCookieID.length;i++){
            ckeCookieID = new Cookie(lstrCookieID[i],this.gstrUserId);
            ckeCookieID.setDomain(pstrDomain);
            ckeCookieID.setPath("/");
            response.addCookie(ckeCookieID);

            ckeCookieID = null;
        }
    }

    public void clearCookieValue(HttpServletResponse response,String pstrDomain,String pstrCookieIDList,String pstrCookieIDSeparateSingle) throws Exception{
        this.gstrUserId=null;
        this.gblnIsValidUser=true;
        setCookieValue(response,pstrDomain,pstrCookieIDList,pstrCookieIDSeparateSingle);
        this.gblnIsValidUser=false;
    }
}
